// TODO: CODE REVIEW & CLEANUP!
//
using System;
using System.Collections.Generic;
using System.Configuration;
using System.Linq;
using System.ServiceProcess;
using System.Windows.Forms;
using System.Xml;
using System.Diagnostics;

namespace HomeUX.MusicServer
{

static class Program
{
    public static bool RunAsWindowsService { get; private set; }
    public static bool OpenWindowOnLaunch { get; private set; }
    public static HashSet<string> Articles { get; private set; }

    /// <summary>
    /// The main entry point for the application.
    /// </summary>
    [STAThread]
    static void Main()
    {
        try
        {
            RunAsWindowsService = GetBooleanAppSetting("RunAsWindowsService");
            OpenWindowOnLaunch = GetBooleanAppSetting("OpenWindowOnLaunch");

            Articles = new HashSet<string>();
            string articlesString = GetAppSetting("Articles");
            foreach (string rawArticle in articlesString.Split(';'))
            {
                string article = rawArticle.Trim().ToLower();
                if (article.Length != 0)
                    Articles.Add(article);
            }

            if (RunAsWindowsService)
            {
                // run this application as a Windows service
				ServiceBase[] servicesToRun = new ServiceBase[] 
				{ 
					new WindowsService() 
				};
				ServiceBase.Run(servicesToRun);
            }
            else
            {
                // run this application as a tray icon
                Application.EnableVisualStyles();
                Application.SetCompatibleTextRenderingDefault(false);
                Application.Run(new AppForm());
            }
        }
        catch (ApplicationException ex)
        {
            Program.ReportError(ex.Message);
            Environment.Exit(1);
        }
    }

    public static string GetSortKey(string value)
    {
        value = value.ToLower();
        foreach (string article in Articles)
        {
            if (value.StartsWith(article + " "))
            {
                value = value.Substring(article.Length + 1) + ", " + article;
                break;
            }
        }

        return value;
    }

    static string GetAppSetting(string settingName)
    {
        string value = ConfigurationManager.AppSettings[settingName];
        if (value == null)
        {
            throw NewApplicationException(
                "Missing <add key=\"{0}\" value=\"...\" /> in <appSettings> in the .config file",
                settingName);
        }
        return value;
    }

    static bool GetBooleanAppSetting(string settingName)
    {
        string stringValue = GetAppSetting(settingName);
        try
        {
            return XmlConvert.ToBoolean(stringValue);
        }
        catch (FormatException)
        {
            throw NewApplicationException(
                "Application setting \"{0}\" (specified in the .config file) has value \"{1}\"; expected \"true\" or \"false\"",
                settingName, stringValue);
        }
    }

    static ApplicationException NewApplicationException(string format, params object[] args)
    {
        return new ApplicationException(Format(format, args));
    }

    // formats a string like String.Format, but if no arguments are passed in then the format
    // string is returned as-is
    public static string Format(string format, params object[] args)
    {
        if ((args == null) || (args.Length == 0))
            return format;
        else
            return String.Format(format, args);
    }

    public static void ReportError(string format, params object[] args)
    {
        ReportMessage(EventLogEntryType.Error, format, args);
    }

    public static void ReportWarning(string format, params object[] args)
    {
        ReportMessage(EventLogEntryType.Warning, format, args);
    }

    public static void ReportInformation(string format, params object[] args)
    {
        ReportMessage(EventLogEntryType.Information, format, args);
    }

    public static void ReportWarningOnlyInWindowsService(string format, params object[] args)
    {
        if (RunAsWindowsService)
            ReportMessage(EventLogEntryType.Warning, format, args);
    }

    public static void ReportInformationOnlyInWindowsService(string format, params object[] args)
    {
        if (RunAsWindowsService)
            ReportMessage(EventLogEntryType.Information, format, args);
    }

    static void ReportMessage(EventLogEntryType logEntryType, string format,
        params object[] args)
    {
        string message = Format(format, args);
        if (RunAsWindowsService)
        {
            using (EventLog log = new EventLog())
            {
                log.Source = "HomeUX Music Server";
                log.WriteEntry(message, logEntryType);
            }
        }
        else
        {
            MessageBoxIcon icon;
            switch (logEntryType)
            {
            case EventLogEntryType.Information:
                icon = MessageBoxIcon.Information;
                break;
            case EventLogEntryType.Warning:
                icon = MessageBoxIcon.Warning;
                break;
            case EventLogEntryType.Error:
            default:
                icon = MessageBoxIcon.Error;
                break;
            }
            MessageBox.Show(message, "HomeUX Music Server", MessageBoxButtons.OK, icon);
        }
    }
}

}
